/*******************************************************************************
 * Copyright (c) 2011 - 2012 TXT e-solutions SpA
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * This work was performed within the IoT_at_Work Project
 * and partially funded by the European Commission's
 * 7th Framework Programme under the research area ICT-2009.1.3
 * Internet of Things and enterprise environments.
 *
 *
 * Authors:
 *     Cristoforo Seccia (TXT e-solutions SpA)
 *     Salvatore Piccione (TXT e-solutions SpA)
 *
 * Contributors:
 *      Domenico Rotondi (TXT e-solutions SpA)
 *******************************************************************************/
package it.txt.access.capability.revocation.wizard.panel.controller;

import it.txt.access.capability.commons.schema.validation.CapabilitySchemaValidationHandler;
import it.txt.access.capability.commons.schema.validation.CapabilitySchemaValidationHandlerException;
import it.txt.access.capability.commons.utils.XMLPrinter;
import it.txt.access.capability.commons.utils.MessageUtils;
import it.txt.access.capability.factory.CapabilitySchemaFactory;
import it.txt.access.capability.factory.CapabilitySchemaFactoryException;
import it.txt.access.capability.revocation.wizard.Wizard;
import it.txt.access.capability.revocation.wizard.WizardPanelController;
import it.txt.access.capability.revocation.wizard.panel.PanelAuthorisingCapabilitySelection;
import it.txt.access.capability.revocation.wizard.panel.objects.AuthorisingCapabilitySelectionResult;
import it.txt.access.capability.schema.AccessRightsCapabilityType;
import it.txt.access.capability.verifier.CapabilityVerifier;
import it.txt.access.capability.verifier.CapabilityVerifierException;
import it.txt.access.capability.verifier.CapabilityVerifierValues;
import it.txt.access.capability.verifier.VerifiedCapability;

import java.awt.Component;
import java.awt.Cursor;
import java.io.File;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JOptionPane;
import javax.xml.datatype.XMLGregorianCalendar;

import org.w3c.dom.Document;

/**
 *
 * @author Cristoforo Seccia (TXT e-solutions SpA)
 * @author Salvatore Piccione (TXT e-solutions SpA - salvatore.piccione AT network.txtgroup.com)
 */
public class ControllerPanelAuthorisingCapabilitySelection extends WizardPanelController {

    private static final Logger LOGGER = Logger.getLogger(ControllerPanelAuthorisingCapabilitySelection.class.getName());
    private static final Cursor defaultCursor = new Cursor(Cursor.DEFAULT_CURSOR);
    private static final Cursor busyCursor = new Cursor(Cursor.WAIT_CURSOR);
    private String recoverAccessRightsCapabilityError = "";
    private boolean isAuthorisingAuCapAvailable = false;
    private AuthorisingCapabilitySelectionResult forwardObject;
    private PanelAuthorisingCapabilitySelection panelAccessType;
    private final int completedPercentage;

    public ControllerPanelAuthorisingCapabilitySelection(Wizard wizard, int completedPercentage, String title) {
        super(wizard);
        panelAccessType = new PanelAuthorisingCapabilitySelection(title, getWizard(), this);
        this.completedPercentage = completedPercentage;
        forwardObject = new AuthorisingCapabilitySelectionResult();
    }

    @Override
    public Component getPanelComponent() {
        return panelAccessType;
    }

    @Override
    public boolean aboutToDisplayPanel() {
//        panelAccessType.validatePanelStatus();
        return true;
    }

    @Override
    public void displayingPanel() {
        getWizard().setBackButtonEnabled(true);
        getWizard().setNextButtonEnabled(isAuthorisingAuCapAvailable);
        getWizard().setFinishButtonEnabled(false);
        getWizard().setCancelButtonEnabled(true);
        getWizard().setAccessRightsCreationPercentage(completedPercentage);
//        panelAccessType.validatePanelStatus();
    }

    @Override
    public boolean aboutToHidePanel() {
        if (isAuthorisingAuCapAvailable) {
            //check if the we have to pass also the revocation issuer
            if (panelAccessType.isAutomaticIssuerInsertionEnabled()) {
                forwardObject.setRevocationIssuer(
                        forwardObject.getAuthorisingCapability().getSubject().getSubjectID().getValue());
            }
            setForwardObject(forwardObject);
            return true;
        } else {
            return false;
        }
    }

//    public void actionPerformed(ActionEvent e) {
//        if (e.getSource() instanceof JRadioButton) {
//            JRadioButton accessTypeRadio = (JRadioButton) e.getSource();
//            String accessType = accessTypeRadio.getName();
//            isAccessPolicyTypeSelected = accessType.equals(ACCESS_POLICY_TYPE) && accessTypeRadio.isSelected();
//            boolean forward = isAccessPolicyTypeSelected || isAccessCapabilityTypeProvided;
//            getWizard().setNextButtonEnabled(forward);
//        }
//    }

//    public String getAccessTypeSelected() {
//        return isAccessPolicyTypeSelected ? ACCESS_POLICY_TYPE : ACCESS_CAPABILITY_TYPE;
//    }

    public boolean recoverAccessRightsCapability(File file) {

        getWizard().setCursor(busyCursor);

        isAuthorisingAuCapAvailable = false;

        String title = "Loading capability token";

        String message = "The authorising capability has been successfully loaded!";

        try {
            AccessRightsCapabilityType capability = 
                    CapabilitySchemaFactory.getInstance().createAccessRights(file);

            CapabilityVerifierValues values = new CapabilityVerifierValues();

            ArrayList<VerifiedCapability> vcs = new ArrayList<VerifiedCapability>();

            if (CapabilityVerifier.accessRightsCapabilityValidityCheck(capability, values, vcs)) {

                LOGGER.log(Level.INFO, "Capability Chain:");
                LOGGER.log(Level.INFO, "************************");
                for (VerifiedCapability verifiedCapability : vcs) {
                    LOGGER.log(Level.INFO, "Capability ID: {0}", verifiedCapability.getCapabilityID());
                    LOGGER.log(Level.INFO, "Capability Issue Date: {0}", verifiedCapability.getIssueDate().toString());
                    LOGGER.log(Level.INFO, "************************");
                }
                Document capabilityDoc = CapabilitySchemaFactory.getInstance().createAccessRightsDocument(capability);
                XMLPrinter.logDocumentElement(capabilityDoc.getDocumentElement(), "Authorising capability", false);
                isAuthorisingAuCapAvailable = true;
                forwardObject.setAuthorisingCapability(capability);
            } else {
                message = "The authorising capability is not valid!";
                recoverAccessRightsCapabilityError = message;
            }
        }
        catch (CapabilitySchemaFactoryException ex) {
            message = ex.getMessage();
            recoverAccessRightsCapabilityError = message;
        } catch (CapabilityVerifierException ex) {
            message = ex.getMessage();
            recoverAccessRightsCapabilityError = message;
        } catch (CapabilitySchemaValidationHandlerException ex) {
            message = ex.getMessage();
            recoverAccessRightsCapabilityError =
                    CapabilitySchemaValidationHandler.dumpValidationEvents(
                    ex.getValidationEvents());
        }

        int type = isAuthorisingAuCapAvailable ? JOptionPane.INFORMATION_MESSAGE : JOptionPane.ERROR_MESSAGE;

        JOptionPane.showMessageDialog(getWizard(), message, title, type);

        getWizard().setNextButtonEnabled(isAuthorisingAuCapAvailable);

        getWizard().setCursor(defaultCursor);

        return isAuthorisingAuCapAvailable;
    }

    public String recoverAccessRightsCapabilityErrorMessage() {
        return MessageUtils.getErrorMessage("Recovering authorising capability", recoverAccessRightsCapabilityError);
    }

    public String getAccessRightsPublicValuesToString() {
        StringBuilder accessRightsPublicValues = new StringBuilder();
        AccessRightsCapabilityType capability = forwardObject.getAuthorisingCapability();
        if (isAuthorisingAuCapAvailable) {
            accessRightsPublicValues.append(MessageUtils.getInfoMessage("Validity Condition Date", null));
            XMLGregorianCalendar notBeforeDate = capability.getValidityCondition().getNotBefore();
            accessRightsPublicValues.append(MessageUtils.getInfoMessage("Not Before", notBeforeDate.toString()));
            XMLGregorianCalendar afterDate = capability.getValidityCondition().getNotOnOrAfter();
            accessRightsPublicValues.append(MessageUtils.getInfoMessage("Not-on-Or After", afterDate.toString()));
            accessRightsPublicValues.append(MessageUtils.getInfoMessage("Issuer", capability.getIssuer().getValue()));
            accessRightsPublicValues.append(MessageUtils.getInfoMessage("Subject ID", capability.getSubject().getSubjectID().getValue()));
            accessRightsPublicValues.append(MessageUtils.getInfoMessage("Resource ID", capability.getResourceID()));
        } else {
            accessRightsPublicValues.append(MessageUtils.getErrorMessage("No Access rights Capability defined.", null));
        }
        return accessRightsPublicValues.toString();
    }
}
